package com.funsport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.funsport.entity.Friend;
import com.funsport.entity.FriendRequest;
import com.funsport.entity.User;
import com.funsport.mapper.FriendMapper;
import com.funsport.mapper.FriendRequestMapper;
import com.funsport.service.IFriendService;
import com.funsport.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 好友服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend> implements IFriendService {
    
    private final FriendRequestMapper friendRequestMapper;
    private final IUserService userService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean sendFriendRequest(Long fromUserId, Long toUserId, String message) {
        // 检查是否已是好友
        if (isFriend(fromUserId, toUserId)) {
            log.warn("用户{}和{}已经是好友", fromUserId, toUserId);
            return false;
        }
        
        // 检查是否已有待处理的申请
        LambdaQueryWrapper<FriendRequest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRequest::getFromUserId, fromUserId)
               .eq(FriendRequest::getToUserId, toUserId)
               .eq(FriendRequest::getStatus, "pending");
        
        if (friendRequestMapper.selectCount(wrapper) > 0) {
            log.warn("用户{}已向{}发送过好友申请", fromUserId, toUserId);
            return false;
        }
        
        // 创建好友申请
        FriendRequest request = new FriendRequest();
        request.setFromUserId(fromUserId);
        request.setToUserId(toUserId);
        request.setMessage(message);
        request.setStatus("pending");
        
        int result = friendRequestMapper.insert(request);
        if (result > 0) {
            log.info("用户{}向{}发送好友申请成功", fromUserId, toUserId);
        }
        return result > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean acceptFriendRequest(Long requestId, Long userId) {
        // 查询申请
        FriendRequest request = friendRequestMapper.selectById(requestId);
        if (request == null || !request.getToUserId().equals(userId)) {
            log.warn("好友申请{}不存在或无权限", requestId);
            return false;
        }
        
        if (!"pending".equals(request.getStatus())) {
            log.warn("好友申请{}状态不是pending", requestId);
            return false;
        }
        
        // 更新申请状态
        request.setStatus("accepted");
        friendRequestMapper.updateById(request);
        
        // 创建双向好友关系
        Friend friend1 = new Friend();
        friend1.setUserId(request.getFromUserId());
        friend1.setFriendId(request.getToUserId());
        save(friend1);
        
        Friend friend2 = new Friend();
        friend2.setUserId(request.getToUserId());
        friend2.setFriendId(request.getFromUserId());
        save(friend2);
        
        log.info("用户{}接受了{}的好友申请", userId, request.getFromUserId());
        return true;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean rejectFriendRequest(Long requestId, Long userId) {
        FriendRequest request = friendRequestMapper.selectById(requestId);
        if (request == null || !request.getToUserId().equals(userId)) {
            return false;
        }
        
        request.setStatus("rejected");
        int result = friendRequestMapper.updateById(request);
        
        if (result > 0) {
            log.info("用户{}拒绝了{}的好友申请", userId, request.getFromUserId());
        }
        return result > 0;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFriend(Long userId, Long friendId) {
        // 删除双向好友关系
        LambdaQueryWrapper<Friend> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friendId);
        remove(wrapper1);
        
        LambdaQueryWrapper<Friend> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(Friend::getUserId, friendId)
                .eq(Friend::getFriendId, userId);
        remove(wrapper2);
        
        log.info("用户{}删除了好友{}", userId, friendId);
        return true;
    }
    
    @Override
    public List<User> getFriendList(Long userId) {
        LambdaQueryWrapper<Friend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Friend::getUserId, userId);
        
        List<Friend> friends = list(wrapper);
        if (friends.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<Long> friendIds = friends.stream()
                                     .map(Friend::getFriendId)
                                     .collect(Collectors.toList());
        
        return userService.listByIds(friendIds);
    }
    
    @Override
    public List<FriendRequest> getFriendRequests(Long userId) {
        LambdaQueryWrapper<FriendRequest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FriendRequest::getToUserId, userId)
               .eq(FriendRequest::getStatus, "pending")
               .orderByDesc(FriendRequest::getCreatedAt);
        
        return friendRequestMapper.selectList(wrapper);
    }
    
    @Override
    public boolean isFriend(Long userId, Long friendId) {
        LambdaQueryWrapper<Friend> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Friend::getUserId, userId)
               .eq(Friend::getFriendId, friendId);
        
        return count(wrapper) > 0;
    }
    
    @Override
    public List<User> searchUsers(String keyword) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(User::getNickname, keyword)
               .or()
               .like(User::getPhone, keyword)
               .last("LIMIT 20");
        
        return userService.list(wrapper);
    }
}

